#include "utils.h"

#include <cstring>

#include <algorithm>

namespace afcore {

bool StringToBool(std::string const& str) {
  std::string lower_str = str;
  std::transform(str.begin(), str.end(), lower_str.begin(), 
    [] (char c) {
      return char(std::tolower(c));
    });
  return "1" == lower_str || "true" == lower_str || "yes" == lower_str;
}

std::string& TrimLeft(std::string& src) {
  size_t pos = src.find_first_not_of(" \r\n\t");
  if (pos != std::string::npos) {
    src.erase(0, pos);
  }
  return src;
}

std::string& TrimRight(std::string& src) {
  size_t pos = src.find_last_not_of(" \r\n\t");
  if (pos != std::string::npos) {
    src.erase(pos + 1);
  }
  return src;
}

std::string& Trim(std::string& src) {
  if (src.empty()) {
    return src;
  }

  return TrimRight(TrimLeft(src));
}

CTokenizer::CTokenizer(const std::string& src, char const delimiter, uint32_t reserve /*= 0*/, bool keep_empty_strings /*= true*/)
{
  str_ = new char[src.length() + 1];
  memcpy(str_, src.c_str(), src.length() + 1);

  if (reserve) {
    storage_.reserve(reserve);
  }

  char* pos_old = str_;
  char* pos_new = str_;

  while(1) {
    if(*pos_new == delimiter) { // 分隔符
      if (keep_empty_strings || pos_old != pos_new) {
        storage_.emplace_back(pos_old);
      }
      pos_old = pos_new + 1;
      *pos_new = '\0';
    } else if ('\0' == *pos_new) { // 结束符
      if (pos_old != pos_new) {
        storage_.emplace_back(pos_old);
      }
      break;
    }

    ++pos_new;
  }
}

} // !namespace afcore